package com.ctl.algorithm;


import java.util.concurrent.Exchanger;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

/**
 * <p>Title: ZeroEvenOddTest</p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2019</p>
 * <p>Company: www.hanshow.com</p>
 *
 * @author ctl
 * @version 1.0
 * @date 2021-09-28 22:35
 */
public class ZeroEvenOddTest {
    static class ZeroEvenOdd {
        int n;

        public ZeroEvenOdd(int n) {
            this.n = n;
        }  // 构造函数

        public void zero(int printNumber) {
            System.out.print(printNumber);
        } // 仅打印出 0

        public void even(int printNumber) {
            System.out.print(printNumber);
        } // 仅打印出 偶数

        public void odd(int printNumber) {
            System.out.print(printNumber);
        } // 仅打印出 奇数
    }

    private static Semaphore zero = new Semaphore(0);
    private static Semaphore odd = new Semaphore(0);
    private static Semaphore even = new Semaphore(0);
    //    private static CountDownLatch countDownLatch = new CountDownLatch(3);
    private static Exchanger<Integer> exchanger = new Exchanger<>();


    public static void main(String[] args) throws Exception {
        int n = 3;
        ZeroEvenOdd zeroEvenOdd = new ZeroEvenOdd(n);
        new Thread(() -> {
            for (int i = 0; i < n; i++) {
                try {
                    zero.acquire();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                zeroEvenOdd.zero(0);
                if (i % 2 == 0) {
                    odd.release();
                } else {
                    even.release();
                }
            }
            System.err.println("over zero");

        }).start();
        new Thread(() -> {
            for (int i = 1; i <= n; i = i + 2) {
                try {
                    odd.acquire();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                zeroEvenOdd.odd(i);
                zero.release();
//                even.release();
            }
            System.err.println("over odd");

        }).start();
        new Thread(() -> {
            for (int i = 2; i <= n; i = i + 2) {
                try {
                    even.acquire();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                zeroEvenOdd.even(i);
                zero.release();
            }
            System.err.println("over even");

        }).start();
        zero.release();
        TimeUnit.SECONDS.sleep(2);
    }
}